#include "hd.h"
#include "status.h"
#include "ex.h"
//#include <avr/eeprom.h>

uint8_t cs=0x00;
uint8_t cs_add=0x00;
unsigned char cs_old=0x00;
unsigned char min_add=0x00;//
unsigned char bf=0x01; //
unsigned char wrong=0x00;
unsigned char yes_no=0x01; //yes? no
uint16_t ControlS=0xff; // 76543210 0 AD 1
unsigned char low_control=0x00;
unsigned char high_control=0x00;
unsigned char alarm_lows=0x00;
unsigned char alarm_highs=0x00;
uint8_t relay_s=0x00;
uint8_t relay_c=0x00;
uint8_t led_s=0x00; //led1 led2 statu 0 led2 1 led1
uint16_t eeStatus0=0xff;//eeprom statu 0 low 1 high 2 address  3 4ma 4 8ma 5 12ma 6 16ma 7 20ma 8 multiple 9 zero 10 con

v_c value;

void( * fp)(void);
typedef void(*FUN_P)(void);//(int Data)
typedef struct Message_Item
{
	unsigned char cStatus;
	FUN_P fnProcess;
}MSG_ITEM;

void fun_cs_add(void)
{
	/*if((key_short)||(key_long))
	{
		bf=0x01;
	}*/
	cs_add++;
	if(cs_add>=disNew)   //display
	{
		cs_add=0x00;
		displayImmediately=0x01;
	}
	else displayImmediately=0x00;
}


void fun_start_00(void) //device on
{
    eepromSet(eeStatusWord0,&eeStatus0,eeReadWord);
	if(eeStatus0&0x0001)
	{
	    value.valueLow=low0;
	}
	else
	{
	    eepromSet(eeValueLowWord0,&value.valueLow,eeReadWord);
	}
	cs=0x01;
}

void fun_start_01(void)
{
    if(eeStatus0&0x0002)
    {
        value.valueHigh=high0;
    }
    else
    {
        eepromSet(eeValueHighWord0,&value.valueHigh,eeReadWord);
    }
    if(eeStatus0&0x0004)
    {
        value.address=address0;
    }
    else
    {
        eepromSet(eeAddressWord,&value.address,eeReadWord);
    }
    if(eeStatus0&0x0008)
    {
        value.valueCurrent4ma=current4ma;
    }
    else
    {
        eepromSet(eeCurrentWord4ma,&value.valueCurrent4ma,eeReadWord);
    }
    cs=0x02;
}

void fun_start_02(void)
{
    if(eeStatus0&0x0010)
    {
        value.valueCurrent8ma=current8ma;
    }
    else
    {
        eepromSet(eeCurrentWord8ma,&value.valueCurrent8ma,eeReadWord);
    }
    if(eeStatus0&0x0020)
    {
        value.valueCurrent12ma=current12ma;
    }
    else
    {
        eepromSet(eeCurrentWord12ma,&value.valueCurrent12ma,eeReadWord);
    }
    if(eeStatus0&0x0040)
    {
        value.valueCurrent16ma=current16ma;
    }
    else
    {
        eepromSet(eeCurrentWord16ma,&value.valueCurrent16ma,eeReadWord);
    }
    cs=0x03;
}

void fun_start_03(void)
{
    if(eeStatus0&0x0080)
    {
        value.valueCurrent20ma=current20ma;
    }
    else
    {
        eepromSet(eeCurrentWord20ma,&value.valueCurrent20ma,eeReadWord);
    }
    if(eeStatus0&0x0100)
    {
        value.valueMultiple=multiple0;
    }
    else
    {
        eepromSet(eeValueMultipleWord0,&value.valueMultiple,eeReadWord);
    }
    if(eeStatus0&0x0200)
    {
        value.valueZero=zero0;
    }
    else
    {
        eepromSet(eeValueZeroWord0,&value.valueZero,eeReadWord);
    }
    cs=0x04;
}

void fun_start_04(void)
{
    if(eeStatus0&0x0400)
    {
        ControlS=0xff;
    }
    else
    {
        eepromSet(eeStateControlByte,&ControlS,eeReadByte);
    }
    cs=0x05;
}

void fun_start_05(void) //0xff
{
	if(displayImmediately)
	{
		displayAll();
		min_add++;
	}
	if(min_add>=2)
	{
	    cs=0x06;
	    min_add=0;
	}
}

void fun_start_06(void) // A
{
    if(displayImmediately)
	{
		symbolTurn(symbolA);
		min_add++;
	}
	if(min_add>=2)
	{
	    cs=0x07;
	    min_add=0;
	}
}

void fun_start_07(void) //a0
{
	if(displayImmediately)
	{
		numberTurn(a0,pointS);
		min_add++;
	}
	if(min_add>=2)
	{
	    cs=0x08;
	    min_add=0;
	}
}

void fun_start_08(void) // H
{
	if(displayImmediately)
	{
		symbolTurn(symbolH);
		high_on;
		min_add++;
	}
	if(min_add>=2)
	{
	    cs=0x09;
	    min_add=0;
	}
}

void fun_start_09(void) //high
{
	if(displayImmediately)
	{
		numberTurn(value.valueHigh,pointS);
		high_on;
		min_add++;
	}
	if(min_add>=2)
	{
	    cs=0x0a;
	    min_add=0;
	}
}

void fun_start_0a(void) // L
{
    if(displayImmediately)
	{
		symbolTurn(symbolL);
		low_on;
		min_add++;
	}
	if(min_add>=2)
	{
	    cs=0x0b;
	    min_add=0;
	}
}

void fun_start_0b(void) //low
{
	if(displayImmediately)
	{
		numberTurn(value.valueLow,pointS);
		low_on;
		min_add++;
	}
	if(min_add>=2)
	{
	    cs=0x0c;
	    min_add=0;
	}
}

void fun_start_0c(void) // add
{
    if(displayImmediately)
	{
		symbolTurn(symbolAdd);
		min_add++;
	}
	if(min_add>=2)
	{
        cs=0x0d;
        min_add=0;
	}
}

void fun_start_0d(void) //address
{
	if(displayImmediately)
	{
		numberTurn(value.address,0);
		min_add++;
	}
	if(min_add>=2)
	{
		cs=0x20;
		value.valueGas=gas0;
		value.dir=dir0;
		min_add=0;
	}
}

void fun_start(void) //
{
	switch(cs)
	{
		case 0x00:
			fp=fun_start_00;
		break;
		case 0x01:
			fp=fun_start_01;
		break;
		case 0x02:
			fp=fun_start_02;
		break;
		case 0x03:
			fp=fun_start_03;
		break;
		case 0x04:
			fp=fun_start_04;
		break;
		case 0x05:
			fp=fun_start_05;
		break;
		case 0x06:
			fp=fun_start_06;
		break;
		case 0x07:
			fp=fun_start_07;
		break;
		case 0x08:
			fp=fun_start_08;
		break;
		case 0x09:
			fp=fun_start_09;
		break;
		case 0x0a:
			fp=fun_start_0a;
		break;
		case 0x0b:
			fp=fun_start_0b;
		break;
		case 0x0c:
			fp=fun_start_0c;
		break;
		case 0x0d:
			fp=fun_start_0d;
		break;
	}
}

void fun_normal_10(void)  // cs=10
{
    symbolTurn(symbolYes);
/*	switch(key_long)
	{
		case 0b00000111:
			if(dis_on)
			{
				min_add++;
				long_led1=1;
				long_led2=1;
				if(min_add==1)
				{
					state_control^=0b00000001;
					CLI();
					eeprom_write_byte((void *)(0x30), state_control);
					SEI();
					relay_s=0x01;
					relay_on;
					if(ee_w1&0x04)
					{
						ee_w1&=0b11111011;
						CLI();
						eeprom_write_byte((void *)(0x3F), ee_w1);
						SEI();
					}
				}
			}
		break;
		case 0b00000110: //set
			if(fun_key_long(m1,0x03))
			{
				cs=0x40;
				m1=0x00;
			}
			m1++;
			m2=0x00;
			m3=0x00;
		break;
		case 0b00000100: //0se
			if(fun_key_long(m2,0x01))
			{
				cs=0x11;
				m2=0x00;
			}
			m1=0x00;
			m2++;
			m3=0x00;
		break;
		case 0b00000010: //gas
			if(fun_key_long(m3,0x02))
			{
				cs=0x12;
				m3=0x00;
			}
			m1=0x00;
			m2=0x00;
			m3++;
		break;
		default:
			m1=0x00;
			m2=0x00;
			m3=0x00;
			min_add=0x00;
			long_led1=0;
			long_led2=0;
	}
	if(relay_s)
	{
		relay_c++;
		if(relay_c==10)
		{
			relay_s=0x00;
			relay_c=0x00;
		}
	}
	if(dis_on)
	{
		g_gas();
		if((value.dir==0)||(value.dir==1))
		{
			if(value.value_gas>=value.value_low)
			{
				relay_on;
				if(value.value_gas<value.value_high) alarm_lows=0x01;
				else alarm_lows=0x00;   //alarm_low();
				if(value.value_gas>=value.value_high) alarm_highs=0x01;
				else alarm_highs=0x00; //alarm_high();
			}
			else
			{
				alarm_lows=0x00;
				alarm_highs=0x00;
				bf=0x01;
				if(!(relay_s)) relay_off;
			}
		}
		else if(value.dir==2)
		{
			if((value.value_gas>=value.value_low)||(value.value_gas<=value.value_high))
			{
				relay_on;
				if(value.value_gas>=value.value_low) alarm_lows=0x01;
				else alarm_lows=0x00;   //alarm_low();
				if(value.value_gas<=value.value_high) alarm_highs=0x01;
				else alarm_highs=0x00; //alarm_high();
			}
			else
			{
				alarm_lows=0x00;
				alarm_highs=0x00;
				bf=0x01;
				if(!(relay_s)) relay_off;
			}
		}
		if(value.value_gas>=a0) value.value_gas=a0;
		if(bf)
		{
			if(relay_s) turn_10(state_control&0x01);
			else turn_10(value.value_gas);
		}
		if(value.value_gas==a0) bf^=0x01; //a0 blink
		point_on=point_on_s;
	}*/
}
/*
void fun_normal_11(void) //0se
{
	if(dis_on)
	{
		if(bf) ad_off(0x02);
		bf^=0x01;
	}
	if(key_short==0x01) cs=0x20;
}

void fun_normal_12(void) //gas
{
	if(dis_on)
	{
		if(bf) ad_off(0x03);
		bf^=0x01;
	}
	if(key_short==0x01) cs=0x30;
}*/

void fun_normal(void)
{
	switch(cs)
	{
		case 0x10:
			fp=fun_normal_10;
		break;
/*		case 0x11:
			fp=fun_normal_11;
		break;
		case 0x12:
			fp=fun_normal_12;
		break;*/
	}
}

void fun_set0_20(void) //cs=20
{
	if(displayImmediately)
	{
		if(countDown(value.g_wADCValue,0))
		{
            uint16_t i_20;
            i_20=value.valueSum>>2;
            if((i_20<zero0-150)||(i_20>zero0+150))
            {
                cs=0x22;
            }
            else
            {
                numberTurn(i_20,0);
                zero_on;
                cs=0x21;
            }
		}
	}
}

void fun_set0_21(void)
{
	if(displayImmediately)
	{
        value.valueZero=(value.valueSum>>2);
        eepromSet(eeValueZeroWord0,&value.valueZero,eeWriteWord);
        if(eeStatus0&0x0200)
        {
            eeStatus0&=0xfdff;
            eepromSet(eeStatusWord0,&eeStatus0,eeWriteWord);
        }
		value.valueSum=0x0000;
		numberTurn(value.valueZero,0);
 //       min_add++;
        zero_on;
 //       if(min_add>=2)
 //       {
            cs=0x10;
 //       }
	}
}

void fun_set0_22(void)
{
	if(displayImmediately)
	{
	    symbolTurn(symbolErr);
	}
	if(key_short==0b00000001) cs=0x10;
}

void fun_set0(void)
{
	switch(cs)
	{
		case 0x20:
			fp=fun_set0_20;
		break;
		case 0x21:
			fp=fun_set0_21;
		break;
		case 0x22:
			fp=fun_set0_22;
		break;
	}
}

void fun_gas_30(void) //cs=30
{
//	if(min_add==0)
//	{
//	    value.adcOldForGas=value.g_wADCValue;
//	}
	if(displayImmediately)
	{
		gas();
        if(countDown(value.valueGas,1))
        {
            value.adcOldForGas=value.g_wADCValue;
            cs=0x01;
        }
	}
}

void fun_gas_31(void)
{
    switch(value.dir)
            {
                case 0:
                    if((value.adcOldForGas-value.valueZero)>threshold)
                    {
                        value.valueGas=(value.valueSum>>2);
                        value.valueSum=0x00;
                        numberTurn(value.valueGas,pointS);
                        cs=0x32;
                    }
                    else cs=0x33;
                break;
                case 1:
                    if((value.valueZero-value.adcOldForGas)>threshold)
                    {
                        value.valueGas=(value.valueSum>>2);
                        value.valueSum=0x00;
                        numberTurn(value.valueGas,pointS);
                        cs=0x32;
                    }
                    else cs=0x33;
                break;
                case 2:
                    if(((value.adcOldForGas+threshold)<value.valueZero)||(value.adcOldForGas>(threshold+value.valueZero)))
                    {
                        value.valueGas=(value.valueSum>>2);
                        value.valueSum=0x00;
                        numberTurn(value.valueGas,pointS);
                        cs=0x32;
                    }
                    else cs=0x33;
                break;
            }
}

void fun_gas_32(void)
{
	if((key_short)||(key_cont)) cs_add=disNew-1;
	if(((key_short==0b00000010)||(key_cont==0b00000010))&&(value.valueGas!=0)) value.valueGas--;
	if(((key_short==0b00000100)||(key_cont==0b00000100))&&(value.valueGas<65535)) value.valueGas++;
	if(value.dir==2)
	{
		if(value.adcOldForGas>value.valueZero)
		{
			if(value.valueGas<gas0) value.valueGas=gas0+1;
		}
		else if(value.adcOldForGas<value.valueZero)
		{
			if(value.valueGas>gas0) value.valueGas=gas0-1;
		}
	}
	numberTurn(value.valueGas,pointS);
	if(key_short==0b00000001)
	{
		switch(value.dir)
		{
			case 0:
				value.valueMultiple=(unsigned int)(((unsigned long)(value.valueGas)<<7)/(unsigned long)(value.adcOldForGas-value.valueZero));
			break;
			case 1:
				value.valueMultiple=(unsigned int)(((unsigned long)(value.valueGas)<<7)/(unsigned long)(value.valueZero-value.adcOldForGas));
			break;
			case 2:
				if(value.adcOldForGas>=value.valueZero) value.valueMultiple=(unsigned int)(((unsigned long)(value.valueGas-gas0)<<7)/(unsigned long)(value.adcOldForGas-value.valueZero));
				else if(value.adcOldForGas<value.valueZero) value.valueMultiple=(unsigned int)(((unsigned long)(gas0-value.valueGas)<<7)/(unsigned long)(value.valueZero-value.adcOldForGas));
			break;
		}
		eepromSet(eeValueMultipleWord0,&value.valueMultiple,eeWriteWord);
		if(eeStatus0&0x0100)
		{
			eeStatus0&=0xfeff;
            eepromSet(eeStatusWord0,&eeStatus0,eeWriteWord);
		}
		cs=0x10;
	}
}

void fun_gas_33(void) //error
{
	if(displayImmediately)
	{
	    symbolTurn(symbolErr);
	}
	if(key_short==0b00000001) cs=0x10;
}

void fun_gas(void)
{
	switch(cs)
	{
		case 0x30:
			fp=fun_gas_30;
		break;
		case 0x31:
			fp=fun_gas_31;
		break;
		case 0x32:
			fp=fun_gas_32;
		break;
		case 0x33:
			fp=fun_gas_33;
		break;
	}
}

void fun_set_40(void) //L
{
	if(displayImmediately)
	{
	    symbolTurn(symbolL);
	    low_on;
	}
	switch(key_short)
	{
		case 0b00000001:
			cs=0x41;
		break;
		case 0b00000100:
			cs=0x42;
		break;
		case 0b00000010:
			cs=0x4e;
		break;
	}
}

void fun_set_41(void)  //LOW
{
	if(lowHigh(&value.valueLow,0x00)) cs=0x40;
}

void fun_set_42(void)  //H
{
	if(displayImmediately)
	{
	    symbolTurn(symbolH);
	    high_on;
	}
	switch(key_short)
	{
		case 0b00000001:
			cs=0x43;
		break;
		case 0b00000100:
			cs=0x44;
		break;
		case 0b00000010:
			cs=0x40;
		break;
	}
}

void fun_set_43(void)  //high
{
	if(lowHigh(&value.valueHigh,0x01)) cs=0x42;
}

void fun_set_44(void) //add
{
	if(displayImmediately)
	{
	    symbolTurn(symbolAdd);
	}
	switch(key_short)
	{
		case 0b00000001:
			cs=0x45;
		break;
		case 0b00000100:
			cs=0x46;
		break;
		case 0b00000010:
			cs=0x42;
		break;
	}
}

void fun_set_45(void) //address
{
	if(fun_ma(&value.address,0x00)) cs=0x44;
}

void fun_set_46(void) //4ma
{
	if(displayImmediately)
	{
	    symbolTurn(symbol4ma);
	}
	switch(key_short)
	{
		case 0b00000001:
			cs=0x47;
		break;
		case 0b00000100:
			cs=0x48;
		break;
		case 0b00000010:
			cs=0x44;
		break;
	}
}

void fun_set_47(void) //4
{
	if(fun_ma(&value.valueCurrent4ma,0x01)) cs=0x46;
}

void fun_set_48(void) //8ma
{
	if(displayImmediately)
	{
	    symbolTurn(symbol8ma);
	}
	switch(key_short)
	{
		case 0b00000001:
			cs=0x49;
		break;
		case 0b00000100:
			cs=0x4a;
		break;
		case 0b00000010:
			cs=0x46;
		break;
	}
}

void fun_set_49(void) //8
{
//	value.value_gas=a_8;
	if(fun_ma(&value.valueCurrent8ma,0x02)) cs=0x48;
}

void fun_set_4a(void) //12ma
{
	if(displayImmediately)
	{
	    symbolTurn(symbol12ma);
	}
	switch(key_short)
	{
		case 0b00000001:
			cs=0x4b;
		break;
		case 0b00000100:
			cs=0x4c;
		break;
		case 0b00000010:
			cs=0x48;
		break;
	}
}

void fun_set_4b(void) //12
{
//	value.value_gas=a_12;
	if(fun_ma(&value.valueCurrent12ma,0x03)) cs=0x4a;
}

void fun_set_4c(void) //16ma
{
	if(displayImmediately)
	{
	    symbolTurn(symbol16ma);
	}
	switch(key_short)
	{
		case 0b00000001:
			cs=0x4d;
		break;
		case 0b00000100:
			cs=0x4e;
		break;
		case 0b00000010:
			cs=0x4a;
		break;
	}
}

void fun_set_4d(void) //16
{
//	value.value_gas=a_16;
	if(fun_ma(&value.valueCurrent16ma,0x04)) cs=0x4c;
}

void fun_set_4e(void) //20ma
{
	if(displayImmediately)
	{
	    symbolTurn(symbol20ma);
	}
	switch(key_short)
	{
		case 0b00000001:
			cs=0x4f;
		break;
		case 0b00000100:
			cs=0x40;
		break;
		case 0b00000010:
			cs=0x4c;
		break;
	}
}

void fun_set_4f(void) //20
{
//	value.value_gas=a0;
	if(fun_ma(&value.valueCurrent20ma,0x05)) cs=0x4e;
}

void fun_set(void)
{
	value.valueGas=0;
	switch(cs)
	{
		case 0x40:
			fp=fun_set_40;
		break;
		case 0x41:
			fp=fun_set_41;
		break;
		case 0x42:
			fp=fun_set_42;
		break;
		case 0x43:
			fp=fun_set_43;
		break;
		case 0x44:
			fp=fun_set_44;
		break;
		case 0x45:
			fp=fun_set_45;
		break;
		case 0x46:
			fp=fun_set_46;
		break;
		case 0x47:
			fp=fun_set_47;
		break;
		case 0x48:
			fp=fun_set_48;
		break;
		case 0x49:
			fp=fun_set_49;
		break;
		case 0x4a:
			fp=fun_set_4a;
		break;
		case 0x4b:
			fp=fun_set_4b;
		break;
		case 0x4c:
			fp=fun_set_4c;
		break;
		case 0x4d:
			fp=fun_set_4d;
		break;
		case 0x4e:
			fp=fun_set_4e;
		break;
		case 0x4f:
			fp=fun_set_4f;
		break;
	}
}

MSG_ITEM MSGMap[]={{0x00,fun_start},{0x01,fun_normal},{0x02,fun_set0},{0x03,fun_gas},{0x04,fun_set}};

void SearchMSGMAP(void) //(unsigned char cStatus)
{
	unsigned char n=0;
//	task_delay[1]=task_delay1;
	for(n=0;n<UBOND(MSGMap);n++)
	{
		if(MSGMap[n].cStatus==(cs>>4)) //(cStatus>>4))
		{
//			g_key();
			fun_cs_add();
//			if(cs_old!=cs)
//			{
//				led1_off;
//				led2_off;
//				min_add=0;
//				cs_old=cs;
//				bf=0x01;
//				cs_add=dis_new-1;
//				point_on=0x00;
//			}
			MSGMap[n].fnProcess();
			( * fp)();
//			if(dis_on) display();
//			if(fun_cd()) cs=0x10;
			break;
		}
	}
}
